package com.sky.aop;

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * ClassName: AutoFillAspect
 * Package: com.sky.aop
 * Description:用于公共字段的填充
 *
 * @Author: Zhang Peiyuan
 * @Create: 2024-12-18-13:34
 * @Version: v1.0
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    // 切入点表达式
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut(){}
    // 前置通知
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint){
        log.info("正在进行公共字段的填充...");
        // 获得方法的注解, 以确定是更新还是插入
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        OperationType value = signature.getMethod().getAnnotation(AutoFill.class).value();

        // 获得方法的参数, 利用反射调用方法
        Object[] args = joinPoint.getArgs();
        if(args == null || args.length == 0){
            return;
        }
        // 获得参数
        Object entity = args[0];
        // 更新时间,和更新人
        try {
            entity.getClass()
                    .getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class)
                    .invoke(entity, LocalDateTime.now());
            entity.getClass()
                    .getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class)
                    .invoke(entity, BaseContext.getCurrentId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 如果是插入操作, 则还需要填充创建时间和创建人
        if(value == OperationType.INSERT){
            try {
                entity.getClass()
                        .getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class)
                        .invoke(entity, LocalDateTime.now());
                entity.getClass()
                        .getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class)
                        .invoke(entity, BaseContext.getCurrentId());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
